package cn.cicoding.mybatis.controller;

import cn.cicoding.mybatis.service.ExcelUserService;
import cn.cicoding.mybatis.bean.UserExcel;
import lombok.SneakyThrows;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * created with IntelliJ IDEA.
 * author: cicoding
 * date: 2020/03/18
 * version: 1.0
 * description:
 */
@Controller
public class UseExcelrController {

    @Resource
    private ExcelUserService excelUserService;


    @RequestMapping("/")
    public String index(Model model) {
        String url = excelUserService.getFilePathByUserId("1");
        model.addAttribute("url", url);
        model.addAttribute("content", "Hello EasyExcel!");
        return "index";
    }

    /**
     * 查询全部 分页查询
     *
     * @param page
     * @param size
     * @return
     */
    @RequestMapping("/listAll")
    @ResponseBody
    public Object listAll(@RequestParam(value = "page", defaultValue = "1") int page,
                          @RequestParam(value = "size", defaultValue = "10") int size) {
        return excelUserService.listAll(page, size);
    }

    /**
     * 初始化数据
     *
     * @return
     */
    @GetMapping("/insert")
    @ResponseBody
    public int insert() {
        return excelUserService.insert();
    }

    /**
     * 删除
     *
     * @param userId
     * @return
     */
    @RequestMapping("/remove")
    @ResponseBody
    public int remove(Integer userId) {
        return excelUserService.remove(userId);
    }

    /**
     * 修改
     *
     * @param user
     * @return
     */
    @RequestMapping("/update")
    @ResponseBody
    public int update(UserExcel user) {
        return excelUserService.update(user);
    }

    /**
     * 多线程导出excel
     * @param response
     */
    @GetMapping("/excel/downloadMultithreading")
    public void downloadMultithreading(HttpServletResponse response) {
        try {
            response.reset();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition",
                    "attachment;filename=user_excel_" + System.currentTimeMillis() + ".xlsx");
            excelUserService.downloadMultithreadingExcel(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 导入excel
     * @param file
     * @param model
     * @return
     */
    @PostMapping("/excel/upload")
    public String upload(@RequestParam(value = "file", required = true) MultipartFile file, Model model) {
        try {
            excelUserService.upload(file.getInputStream());
        } catch (Exception e) {
            e.printStackTrace();
            return "success";
        }
        model.addAttribute("content", "上传成功！");
        return "success";
    }

    /**
     * 多sheel导出excel
     * @param response
     */
    @GetMapping("/excel/downloads")
    public void downloads(HttpServletResponse response) {
        try {
            response.reset();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition",
                    "attachment;filename=user_excel_" + System.currentTimeMillis() + ".xlsx");
            excelUserService.downloadExcels(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    /**
     * 导出excel
     * @param response
     */
    @GetMapping("/excel/download")
    public void download(HttpServletResponse response) {
        try {
            response.reset();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition",
                    "attachment;filename=user_excel_" + System.currentTimeMillis() + ".xlsx");
            excelUserService.downloadExcel(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 注意事项
     *  * 异步处理: 上述示例使用了Spring的@Async注解进行异步处理，确保导出操作不会阻塞主线程。
     *  * 文件存储: 实际部署时，你需要根据实际情况选择合适的文件存储策略，可能是服务器的文件系统、云存储服务等。
     *  * 通知机制: 本示例未包含用户通知机制，你可能需要通过邮件、短信或消息队列等方式，在导出完成后通知用户下载。
     *  * 安全性: 确保下载链接的安全性，避免未授权访问。
     *  * 资源清理: 实现适当的文件清理策略，避免长时间占用存储空间。
     * 触发异步后台导出操作
     * @param userId
     * @return
     */
    @GetMapping("/export/start/{userId}")
    @ResponseBody
    public String startExport(@PathVariable String userId) {
        excelUserService.exportDataAsync(userId);
        return "Export started. Please wait for the notification to download.";
    }

    /**
     * 用户主动请求下载
     * @param userId
     * @param response
     * @throws IOException
     */
    @SneakyThrows
    @GetMapping("/download/{userId}")
    public void downloadExcel(@PathVariable String userId, HttpServletResponse response) {
        String filePath = excelUserService.getFilePathByUserId(userId);
        if (filePath != null) {
            File file = new File(filePath);
            if (file.exists()) {
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.setHeader("Content-Disposition", "attachment;filename=" + new String(file.getName().getBytes(), "ISO-8859-1"));

                try (FileInputStream fis = new FileInputStream(file); OutputStream os = response.getOutputStream()) {
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = fis.read(buffer)) > 0) {
                        os.write(buffer, 0, length);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "File not found.");
            }
        } else {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No export task associated with this user ID.");
        }
    }


}
